package com.example.aicloud.controller;

import com.example.aicloud.entity.Answer;
import com.example.aicloud.entity.enums.AiModelEnum;
import com.example.aicloud.entity.enums.AiTypeEnum;
import com.example.aicloud.service.IAnswerService;
import com.example.aicloud.util.AppVariable;
import com.example.aicloud.util.ResponseEntity;
import com.example.aicloud.util.SecurityUtil;
import jakarta.annotation.Resource;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiImageClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * 调用本地OpenAI大模型
 */
@RestController // 等于@Controller + @ResponseBody, 表示返回的数据是json格式
@RequestMapping("/chatgpt") //用于将 HTTP 请求映射到特定的处理方法上,可以在类级别和方法级别使用
public class ChatGptController {
    @Resource
    private OllamaChatClient chatModel;
    @Resource
    private IAnswerService answerService;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    /**
     * 调用 OpenAI 聊天接口
     * @param question
     * @return
     */
    @PostMapping("/chat")
    public ResponseEntity chat(String question)  {
        if (!StringUtils.hasLength(question)){
            // 输入为空
            return ResponseEntity.fail("输入内容不能为空!");
        }
        String result= "";  // 大模型返回结果
        boolean addResult = false; // 数据添加状态
        // 执行分布式锁
        // key
        String lockKey = AppVariable.getModelLockKey(SecurityUtil.getCurrentUser().getUid(), AiModelEnum.OPENAI.getValue(), AiTypeEnum.CHAT.getValue());
        // 1. 获取分布式锁实例
        RLock rLock = redissonClient.getLock(lockKey);
        try {
            // 2. 获取分布式锁
            boolean isLock = rLock.tryLock(30, TimeUnit.SECONDS); //设置最长等待时间30秒
            if (!isLock){
                return ResponseEntity.fail("请勿频繁调用接口！");
            }
            // 调用 OpenAI 接口
            result= chatModel.call(question);
            // 将结果保存到数据库
            Answer answer=Answer.builder()
                    .title(question)
                    .model(AiModelEnum.OPENAI.getValue())
                    .type(AiTypeEnum.CHAT.getValue())
                    .uid(SecurityUtil.getCurrentUser().getUid())
                    .content(result)
                    .build();
            addResult = answerService.save(answer);
        }catch ( Exception e){

        }finally {
            // 3. 释放分布式锁
            rLock.unlock();
        }

        if (addResult){
            return ResponseEntity.success(result);
        }else {
            return ResponseEntity.fail("数据保存失败，请重试！");
        }
    }
}
